﻿// ----------------------------------------------------------------------------------------
// Author:                    Joaquín López y Magally Vargas
// Company:                   Albalia Interactiva S.L
// Assembly version:          1.0.0.0
// Date:                      10/02/2009
// Time:                      12:15
// Solution Name:             FacturaeAdd-in
// Solution Filename:         FacturaeAdd-in.sln
// Solution FullFilename:     C:\Ribbon_Facturae\FacturaeAdd-in.sln
// Project Name:              FinalTemplate
// Project Filename:          FinalTemplate.csproj
// Project FullFilename:      C:\Ribbon_Facturae\FinalTemplate\FinalTemplate\FinalTemplate.csproj
// Project Item Name:         ThisDocument.cs
// Project Item Filename:     ThisDocument.cs
// Project Item FullFilename: C:\Ribbon_Facturae\FinalTemplate\FinalTemplate\ThisDocument.cs
// Project Item Kind:         Código
// Purpose:                   Diseño y funcionalidad del documento de Word como plantilla de facturae
//Copyright © 2008 - 2009 Albalia Interactiva S.L. Reservados todos los derechos.
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml.Linq;
using Microsoft.VisualStudio.Tools.Applications.Runtime;
using Office = Microsoft.Office.Core;
using Word = Microsoft.Office.Interop.Word;
using System.Xml.Serialization;
using System.Globalization;
using System.Reflection;
using Microsoft.Office.Tools.Word;
using System.IO;
using System.Xml;
using Microsoft.Office.Interop.Word;

namespace FinalTemplate
{
    /// <summary>
    /// Clase que contiene la personalización del documento de Word, para darle la funcionalidad de plantilla de cálculos.
    /// y asigna los controles para completar los datos de la facturae
    /// </summary>
    public partial class ThisDocument
    {

        #region Fields

        CultureInfo cInfo;
        String language;
        string languajePath;
        string messagePath;


        /// <summary>
        /// array de caracteres a eliminar de los valores tomados directamente de las celdas de una table
        /// </summary>
        char[] x = { '\r', '\a', '\n' };

        /// <summary>
        /// base sobre la que se calculan los descuentos generales
        /// </summary>
        double GeneralDiscountBase;

        /// <summary>
        /// totalGrossAmount = el monto total bruto antes de los descuentos generales
        /// </summary>
        
        double totalGrossAmount;


        /// <summary>
        /// totalGeneralDiscount = total de los descuentos generales
        /// </summary>
        double totalGeneralDiscount;

        /// <summary>
        ///  TotalTaxesOutputs = total de impuestos repercutidos
        /// </summary>
        double TotalTaxesOutputs;


        /// <summary>
        /// TotalTaxesWithHeld = total de impuestos retenidos
        /// </summary>
        double TotalTaxesWithHeld;

        /// <summary>
        /// almacena el indice de la tabla principal, donde se encuantran los datos de las partes, emisor y cliente
        /// </summary>
        int t1;

        /// <summary>
        /// almacena el índice de la tabla de detalles
        /// </summary>
        int t2;

        /// <summary>
        /// almacena el índice de la tabla de descuentos
        /// </summary>
        int t3;
        
        /// <summary>
        /// almacena el índice de la tabla de observaciones
        /// </summary>
        int t4;

        /// <summary>
        /// almacena el índice de la tabla de totales
        /// </summary>
        int t5;

        /// <summary>
        /// almacena el indice de la tabla de informacion de tercero
        /// </summary>
        int t6;

        /// <summary>
        /// almacena la cultura del sistema, para control de conversion de datos, tomando en cuenta separadores de decimales y de millares
        /// </summary>
        CultureInfo culture;

        /// <summary>
        /// define los separadors de decimales y millares
        /// </summary>
        NumberFormatInfo num;

        XmlDocument docLanguage; 
        
        #endregion



        #region Código generado por el Diseñador de VSTO

        /// <summary>
        /// Método necesario para admitir el Diseñador. No se puede modificar
        /// el contenido del método con el editor de código.
        /// </summary>
        private void InternalStartup()
        {
            this.btDeleteDiscount.Click += new System.EventHandler(this.btDeleteDiscount_Click);
            this.btAddDiscount.Click += new System.EventHandler(this.btAddDiscount_Click);
            this.btModifyDetail.Click += new System.EventHandler(this.btModifyDetail_Click);
            this.btDeleteDetail.Click += new System.EventHandler(this.btDeleteDetail_Click);
            this.btAddDetails.Click += new System.EventHandler(this.btAddDetails_Click);
            this.btModifyDiscount.Click += new System.EventHandler(this.btModifyDiscount_Click);
            this.txtCifEM.Exiting += new System.EventHandler<Microsoft.Office.Tools.Word.ContentControlExitingEventArgs>(this.txtCifEM_Exiting);
            this.cbxCountryEM.Exiting += new System.EventHandler<Microsoft.Office.Tools.Word.ContentControlExitingEventArgs>(this.cbxCountryEM_Exiting);
            this.cbxIVA.Exiting += new System.EventHandler<Microsoft.Office.Tools.Word.ContentControlExitingEventArgs>(this.cbxIVA_Exiting);
            this.cbxCountryTH.Exiting += new System.EventHandler<Microsoft.Office.Tools.Word.ContentControlExitingEventArgs>(this.cbxCountryTH_Exiting);
            this.txtCIFTH.Entering += new System.EventHandler<Microsoft.Office.Tools.Word.ContentControlEnteringEventArgs>(this.txtCIFTH_Entering);
            this.txtCifBP.Exiting += new System.EventHandler<Microsoft.Office.Tools.Word.ContentControlExitingEventArgs>(this.txtCifBP_Exiting);
            this.cbxCountryBP.Exiting += new System.EventHandler<Microsoft.Office.Tools.Word.ContentControlExitingEventArgs>(this.cbxCountryBP_Exiting);
            this.txtUd.Exiting += new System.EventHandler<Microsoft.Office.Tools.Word.ContentControlExitingEventArgs>(this.txtUd_Exiting);
            this.txtPrice.Exiting += new System.EventHandler<Microsoft.Office.Tools.Word.ContentControlExitingEventArgs>(this.txtPrice_Exiting);
            this.txtDiscount.Exiting += new System.EventHandler<Microsoft.Office.Tools.Word.ContentControlExitingEventArgs>(this.txtDiscount_Exiting);
            this.txtIRPF.Exiting += new System.EventHandler<Microsoft.Office.Tools.Word.ContentControlExitingEventArgs>(this.txtIRPF_Exiting);
            this.txtDiscountRate.Exiting += new System.EventHandler<Microsoft.Office.Tools.Word.ContentControlExitingEventArgs>(this.txtDiscountRate_Exiting);
            this.Shutdown += new System.EventHandler(this.ThisDocument_Shutdown);
            this.Startup += new System.EventHandler(this.ThisDocument_Startup);

        }

        #endregion


        #region EventHandlers Methods

        /// <summary>
        /// se ejcuta al abrirse un documento de basado en la plantilla
        /// Carga los combobox de país, de emisor de la factura y de moneda
        /// inicializa los totales. y protege la tabla principal 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ThisDocument_Startup(object sender, System.EventArgs e)
        {
            CultureInfo cInfo = new CultureInfo(this.Application.LanguageSettings.get_LanguageID(Microsoft.Office.Core.MsoAppLanguageID.msoLanguageIDUI));
            String language = cInfo.Name;

            languajePath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\Microsoft Office Word Facturae Add-In\Datos de Programa\Languages\" + language + ".xml";
            messagePath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\Microsoft Office Word Facturae Add-In\Datos de Programa\Messages\" + language + ".xml";

            this.Application.DocumentBeforeSave += new Microsoft.Office.Interop.Word.ApplicationEvents4_DocumentBeforeSaveEventHandler(Application_DocumentBeforeSave);

            culture = CultureInfo.InstalledUICulture;
            num = culture.NumberFormat;

            try
            {
                enumerateTables();

                try
                {
                    this.cbxCountryEM.DropDownListEntries.Clear();
                    this.cbxCountryBP.DropDownListEntries.Clear();                    
                    this.cbxCurrency.DropDownListEntries.Clear();


                    string  path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\Microsoft Office Word Facturae Add-In\Datos de Programa\InformationFiles\"+ language+ @"\Countries.txt";

                    string[] data = { "Afganistán", "AFG", "Albania", "ALB", "Alemania", "DEU", "Andorra", "AND", "Angola", "AGO", "Anguilla", "AIA", "Antigua y Barbuda", "ATG", "Antillas Holandesas", "ANT", "Arabia Saudí", "SAU", "Argelia", "DZA", "Argentina", "ARG", "Armenia", "ARM", "Aruba", "ABW", "ARY Macedonia", "MKD", "Australia", "AUS", "Austria", "AUT", "Azerbaiyán", "AZE", "Bahamas", "BHS", "Bahréin", "BHR", "Bangladesh", "BGD", "Barbados", "BRB", "Bélgica", "BEL", "Belice", "BLZ", "Benin", "BEN", "Bermudas", "BMU", "Bhután", "BTN", "Bielorrusia", "BLR", "Bolivia", "BOL", "Bosnia y Herzegovina", "BIH", "Botsuana", "BWA", "Brasil", "BRA", "Brunéi", "BRN", "Bulgaria", "BGR", "Burkina Faso", "BFA", "Burundi", "BDI", "Cabo Verde", "CPV", "Camboya", "KHM", "Camerún", "CMR", "Canadá", "CAN", "Chad", "TCD", "Chile", "CHL", "China", "CHN", "Chipre", "CYP", "Ciudad del Vaticano", "VAT", "Colombia", "COL", "Comoras", "COM", "Congo", "COG", "Corea del Norte", "PRK", "Corea del Sur", "KOR", "Costa de Marfil", "CIV", "Costa Rica", "CRI", "Croacia", "HRV", "Cuba", "CUB", "Dinamarca", "DNK", "Dominica", "DMA", "Ecuador", "ECU", "Egipto", "EGY", "El Salvador", "SLV", "Emiratos Árabes Unidos", "ARE", "Eritrea", "ERI", "Eslovaquia", "SVK", "Eslovenia", "SVN", "España", "ESP", "Estados Unidos", "USA", "Estonia", "EST", "Etiopía", "ETH", "Filipinas", "PHL", "Finlandia", "FIN", "Fiyi", "FJI", "Francia", "FRA", "Gabón", "GAB", "Gambia", "GMB", "Georgia", "GEO", "Ghana", "GHA", "Gibraltar", "GIB", "Granada", "GRD", "Grecia", "GRC", "Groenlandia", "GRL", "Guadalupe", "GLP", "Guam", "GUM", "Guatemala", "GTM", "Guayana Francesa", "GUF", "Guernsey", "GGY", "Guinea", "GIN", "Guinea Ecuatorial", "GNQ", "Guinea-Bissau", "GNB", "Guyana", "GUY", "Haití", "HTI", "Honduras", "HND", "Hong Kong", "HKG", "Hungría", "HUN", "India", "IND", "Indonesia", "IDN", "Irán", "IRN", "Iraq", "IRQ", "Irlanda", "IRL", "Isla de Man", "IMN", "Isla Norfolk", "NFK", "Islandia", "ISL", "Islas Caimán", "CYM", "Islas Cook", "COK", "Islas Feroe", "FRO", "Islas Malvinas", "FLK", "Islas Marianas del Norte", "MNP", "Islas Marshall", "MHL", "Islas Pitcairn", "PCN", "Islas Salomón", "SLB", "Islas Turcas y Caicos", "TCA", "Islas Vírgenes Británicas", "VGB", "Islas Vírgenes de los Estados Unidos", "VIR", "Israel", "ISR", "Italia", "ITA", "Jamaica", "JAM", "Japón", "JPN", "Jersey", "JEY", "Jordania", "JOR", "Kazajstán", "KAZ", "Kenia", "KEN", "Kirguistán", "KGZ", "Kiribati", "KIR", "Kuwait", "KWT", "Laos", "LAO", "Lesotho", "LSO", "Letonia", "LVA", "Líbano", "LBN", "Liberia", "LBR", "Libia", "LBY", "Liechtenstein", "LIE", "Lituania", "LTU", "Luxemburgo", "LUX", "Macao", "MAC", "Madagascar", "MDG", "Malasia", "MYS", "Malawi", "MWI", "Maldivas", "MDV", "Malí", "MLI", "Malta", "MLT", "Marruecos", "MAR", "Martinica", "MTQ", "Mauricio", "MUS", "Mauritania", "MRT", "Mayotte", "MYT", "México", "MEX", "Micronesia", "FSM", "Moldavia", "MDA", "Mónaco", "MCO", "Mongolia", "MNG", "Montenegro", "MNE", "Montserrat", "MSR", "Mozambique", "MOZ", "Myanmar", "MMR", "Namibia", "NAM", "Nauru", "NRU", "Nepal", "NPL", "Nicaragua", "NIC", "Níger", "NER", "Nigeria", "NGA", "Niue", "NIU", "Noruega", "NOR", "Nueva Caledonia", "NCL", "Nueva Zelanda", "NZL", "Omán", "OMN", "Países Bajos", "NLD", "Pakistán", "PAK", "Palau", "PLW", "Palestina", "PSE", "Panamá", "PAN", "Papúa Nueva Guinea", "PNG", "Paraguay", "PRY", "Perú", "PER", "Polinesia Francesa", "PYF", "Polonia", "POL", "Portugal", "PRT", "Puerto Rico", "PRI", "Qatar", "QAT", "Reino Unido", "GBR", "República Centroafricana", "CAF", "República Checa", "CZE", "República Democrática del Congo", "COD", "República Dominicana", "DOM", "Reunión", "REU", "Ruanda", "RWA", "Rumania", "ROU", "Rusia", "RUS", "Sahara Occidental", "ESH", "Samoa", "WSM", "Samoa Americana", "ASM", "San Cristóbal y Nevis", "KNA", "San Marino", "SMR", "San Pedro y Miquelón", "SPM", "San Vicente y las Granadinas", "VCT", "Santa Helena", "SHN", "Santa Lucía", "LCA", "Santo Tomé y Príncipe", "STP", "Senegal", "SEN", "Serbia", "SRB", "Seychelles", "SYC", "Sierra Leona", "SLE", "Singapur", "SGP", "Siria", "SYR", "Somalia", "SOM", "Sri Lanka", "LKA", "Suazilandia", "SWZ", "Sudáfrica", "ZAF", "Sudán", "SDN", "Suecia", "SWE", "Suiza", "CHE", "Surinam", "SUR", "Svalbard y Jan Mayen", "SJM", "Tailandia", "THA", "Taiwán", "TWN", "Tanzania", "TZA", "Tayikistán", "TJK", "Timor Oriental", "TLS", "Togo", "TGO", "Tokelau", "TKL", "Tonga", "TON", "Trinidad y Tobago", "TTO", "Túnez", "TUN", "Turkmenistán", "TKM", "Turquía", "TUR", "Tuvalu", "TUV", "Ucrania", "UKR", "Uganda", "UGA", "Uruguay", "URY", "Uzbekistán", "UZB", "Vanuatu", "VUT", "Venezuela", "VEN", "Vietnam", "VNM", "Wallis y Futuna", "WLF", "Yemen", "YEM", "Yibuti", "DJI", "Zaire", "ZAR", "Zambia", "ZMB", "Zimbabue", "ZWE" };
                    
                    char []sep = {','};

                    string datos = ReadFile(path);

                    if (!string.IsNullOrEmpty(datos))
                    {
                        data = datos.Replace("\r\n", "").Trim().Split(',');
                    }


                    this.lbnDetails.Text = LoadLabel(languajePath, lbnDetails.Name);
                    this.lbnDiscounts.Text = LoadLabel(languajePath, lbnDetails.Name);

                    LoadComboBox(this.cbxCountryEM, data);
                    LoadComboBox(this.cbxCountryBP, data);

                    string pathCorrectiveReason = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\Microsoft Office Word Facturae Add-In\Datos de Programa\InformationFiles\"+ language;

                    loadCorrectiveReason(pathCorrectiveReason + @"\correctionReason.txt", "CORR_ReasonDescription");
                    loadCorrectiveReason(pathCorrectiveReason + @"\correctionMethod.txt", "CORR_CorrectionMethodDescription");
                    try
                    {
                        this.cbxCountryTH.DropDownListEntries.Clear();
                        LoadComboBox(this.cbxCountryTH, data);
                    }
                    catch (Exception) { }


                }
                catch (Exception) { }


                foreach (int item in Enum.GetValues(typeof(CurrencyCodeType)))
                {
                    this.cbxCurrency.DropDownListEntries.Add(Enum.GetName(typeof(CurrencyCodeType), item), Enum.GetName(typeof(CurrencyCodeType), item), item);

                }

                dtpIssueDate.Text = DateTime.Today.ToString();
                dtpDevengo.Text = DateTime.Today.ToString();               

            }

            catch (Exception) { }

            try
            {
                cargarN_Fila(this.cbxnDetails, t2);
                cargarN_Fila(this.cbxnDiscount, t3);
            }
            catch (Exception) { }

            try
            {
                this.Tables[1].Range.Select();
                this.Controls.AddGroupContentControl("groupt");
                this.dtpIssueDate.Range.Select();

            }
            catch (Exception) { }

            try
            {
                if (t6 == 0)
                {
                    this.cbxIssuerType.DropDownListEntries.Clear();
                    this.cbxIssuerType.DropDownListEntries.Add(LoadLabel(languajePath,"itemReceptor"), "RE", 0);
                    this.cbxIssuerType.DropDownListEntries.Add(LoadLabel(languajePath,"itemEmisor"), "EM", 1);
                    
                }
            }
            catch (Exception) { }
            
        }

        private void loadCorrectiveReason(string path, string tag)
        {
            try
            {
                string datos = ReadFile(path);
                string [] data;
                Microsoft.Office.Interop.Word.ContentControl ctr = getControlByTag(tag);
                if (ctr != null)
                {
                    if (!string.IsNullOrEmpty(datos))
                    {
                        data = datos.Replace("\r\n", "").Trim().Split(',');
                        ctr.DropdownListEntries.Clear();
                      
                        try
                        {
                            int index = 0;
                            for (int i = 0; i < data.Length; i++)
                            {
                                ctr.DropdownListEntries.Add(data[i], data[i + 1], index);
                                i++; index++;
                            }

                        }
                        catch (Exception){}
                    }
                }
                
               
            }
            catch (Exception bh) 
            {
            }
        }

        /// <summary>
        /// Método que busca un control por su tag y lo devuelve
        /// </summary>
        /// <param name="tag">Parámetro con el tag del control a buscar</param>
        /// <returns>El ContentControl con el tag especificado por parámetro o null si no se encuentra</returns>
        public Microsoft.Office.Interop.Word.ContentControl getControlByTag(String tag)
        {
            Microsoft.Office.Interop.Word.ContentControl cc = null;
            try
            {
                foreach (Microsoft.Office.Interop.Word.ContentControl item in this.ContentControls)
                {
                    if (!string.IsNullOrEmpty(item.Tag))
                    {
                        if (item.Tag.ToLower().Equals(tag.ToLower()))
                        {
                            cc = item; break;
                        }

                    }
                }
            }
            catch (Exception) { }
            return cc;
        }

        /// <summary>
        /// antes de guardarse un documento basado en esta plantilla, llama al método protectIssuedDocument(), que bloquea el documento, si ç
        /// el estado es recibido o emitido
        /// </summary>
        /// <param name="Doc"></param>
        /// <param name="SaveAsUI"></param>
        /// <param name="Cancel"></param>
        private void Application_DocumentBeforeSave(Microsoft.Office.Interop.Word.Document Doc, ref bool SaveAsUI, ref bool Cancel)
        {
            protectIssuedDocument();
        }

        private void ThisDocument_Shutdown(object sender, System.EventArgs e)
        {
            

        }

        /// <summary>
        /// Método que devuelve una cádena con los datos almacenados en el archivo especificado en 
        /// el path que recibe por parámetro.
        /// </summary>
        /// <param name="path">Ruta del archivo que vamos a leer</param>
        /// <returns>Un string con los datos en forma de cadena</returns>
        public string ReadFile(string path)
        {
            try
            {
                using (StreamReader sr = new StreamReader(path, Encoding.Default))
                {
                    return sr.ReadToEnd();
                }
            }
            catch (Exception) { return ""; }
        }
        
        /// <summary>
        /// evento del botón agregar detalles.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btAddDetails_Click(object sender, EventArgs e)
        {
            try
            {
                enumerateTables();
                InitTotals();
                addDetail(this.Tables[t2].Rows.Last.Index, true);
                cargarN_Fila(this.cbxnDetails, t2);
                modifyDiscount();
            }
            catch (Exception) { }
        }       

        /// <summary>
        /// evento del botón agregar descuentos
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btAddDiscount_Click(object sender, EventArgs e)
        {

            enumerateTables();
            if (this.Tables[t2].Rows.Count > 3)
            {
                InitTotals();
                addDiscount(this.Tables[t3].Rows.Last.Index, true);
                cargarN_Fila(this.cbxnDiscount, t3);
            }
        }

       /// <summary>
       /// Evento del botón modificar detalles
       /// </summary>
       /// <param name="sender"></param>
       /// <param name="e"></param>
        private void btModifyDetail_Click(object sender, EventArgs e)
        {
            try
            {
                enumerateTables();
                ResetTotals();

                if (this.Tables[t2].Rows.Count > 3)
                {
                    for (int i = 3; i < this.Tables[t2].Rows.Count; i++)
                    {
                        addDetail(i, false);
                    }

                    cargarN_Fila(this.cbxnDetails, t2);

                    modifyDiscount();
                }
            }
            catch (Exception) { }


        }

        /// <summary>
        /// Evento del botón eliminar detalles
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btDeleteDetail_Click(object sender, EventArgs e)
        {

            try
            {
                enumerateTables();
                string selectedRow = string.Empty;

                try
                {
                    selectedRow = this.cbxnDetails.SelectedValue.ToString();
                }
                catch (Exception)
                {
                    cargarN_Fila(cbxnDetails, t2);
                    MessageBox.Show(LoadLabel(languajePath,"lbnDetails"),"Detalles", MessageBoxButtons.OK, MessageBoxIcon.Stop, MessageBoxDefaultButton.Button1);
                }

                if (!string.IsNullOrEmpty(selectedRow))
                {
                    try
                    {

                        int deletedRow = int.Parse(selectedRow);

                        
                        try
                        {


                            if (this.Tables[t2].Rows.Count > 3)
                            {
                                this.Tables[t2].Rows[deletedRow].Delete();
                                ResetTotals();

                                for (int i = 3; i < this.Tables[t2].Rows.Count; i++)
                                {
                                    addDetail(i, false);
                                }

                                cargarN_Fila(this.cbxnDetails, t2);
                                modifyDiscount();
                                updateResultsTable();
                            }
                            else
                            {
                                ResetTotals();
                                updateResultsTable();
                            }

                            if (this.Tables[t2].Rows.Count == 3)
                            {
                                for (int j = this.Tables[t3].Rows.Count - 1; j >= 3; j--)
                                {
                                    this.Tables[t3].Rows[j].Delete();
                                    cargarN_Fila(cbxnDiscount, t3);
                                    ResetTotals();
                                    totalGeneralDiscount = 0.0d;
                                    GeneralDiscountBase = 0.0d;
                                    updateResultsTable();
                                }
                            }
                        }
                        catch (Exception) { }


                    }
                    catch (Exception) { }

                }

            }
            catch (Exception) { }
        }

        /// <summary>
        /// Evento del botón modificar descuentos
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btModifyDiscount_Click(object sender, EventArgs e)
        {
            try
            {
                modifyDiscount();
            }
            catch (Exception) { }

        }

        /// <summary>
        /// evento del botón eliminar descuentos
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btDeleteDiscount_Click(object sender, EventArgs e)
        {
            try
            {
                enumerateTables();

                InitTotals();

                string selectedRow = string.Empty;

                try
                {
                    selectedRow = this.cbxnDiscount.SelectedValue.ToString();
                }
                catch (Exception)
                {
                    cargarN_Fila(cbxnDiscount, t3);
                    MessageBox.Show(LoadLabel(languajePath,"lbnDetails"),LoadLabel(messagePath,"captionDiscounts"), MessageBoxButtons.OK, MessageBoxIcon.Stop, MessageBoxDefaultButton.Button1);
                }

                if (!string.IsNullOrEmpty(selectedRow))
                {

                    try
                    {

                        int deletedRow = int.Parse(selectedRow);

                        if (this.Tables[t3].Rows.Count > 3)
                        {
                            deleteDiscount(deletedRow);
                            this.Tables[t3].Rows[deletedRow].Delete();
                            cargarN_Fila(this.cbxnDiscount, t3);
                        }

                    }
                    catch (Exception exc) { throw exc; }
                }
            }
            catch (Exception) { }
            
        }



        #endregion

        #region private Methods

        /// <summary>
        /// método que se encarga de identificar los indices de las tablas.
        /// <para>
        /// Cada una de las tablas tiene un número en el encabezado, que permite identificarlas sin importar el orden en que aparezcan,
        /// se llama al inicio de cada operacion de cálculos,para aseguraserse de que las las variables de los indices esten actualizadas
        /// en caso de que una tabla haya sido eliminada
        /// 
        /// <example>
        /// se toma el texto del encabezado de la tabla, 
        /// 
        /// <code>string table = this.Tables[i].Rows[1].Cells[1].Range.Text.Trim(x).Trim();</code>
        /// 
        /// con base en el valor de "table", se asigna el indice a cada una de las variables para indices, t1,t2,t3,t4.t5,t6
        /// </example>
        /// </para>
        /// 
        /// </summary>
        private void enumerateTables()
        {
            try
                {
                    for (int i = 2; i <= this.Tables.Count; i++)
                    {

                        string table = this.Tables[i].Rows[1].Cells[1].Range.Text.Trim(x).Trim();

                        switch (table)
                        {

                            case "2":
                                t2 = i; break;
                            case "3":
                                t3 = i; break;
                            case "6":
                                t4 = i; break;
                            case "4":
                                t5 = i; break;
                            case "1":
                                t6 = i; break;
                            //case "7":
                            //    t7 = i; break;

                        }
                    }
                }
                catch (Exception) { }
            

        }

       
        /// <summary>
        /// inicializa los totales, para retomar los cálculos cuando un documento ha sido guardado sin finalizar de realizar operaciones
        /// </summary>
        private void InitTotals()
        {
            try
            {
                totalGrossAmount = double.Parse(this.Tables[t5].Rows[2].Cells[3].Range.Text.Trim(x).Trim(), num);                
                totalGeneralDiscount = double.Parse(this.Tables[t5].Rows[3].Cells[3].Range.Text.Trim(x).Trim(), num);
                GeneralDiscountBase = totalGrossAmount;
                TotalTaxesWithHeld = double.Parse(this.Tables[t5].Rows.Last.Previous.Cells[3].Range.Text.Trim(x).Trim(), num);
            }
            catch (Exception) { }

        }


        /// <summary>
        /// establece los totales en 0, y elimina de las lineas correspondientes a Iva de las tablas de totales
        /// </summary>
        private void ResetTotals()
        {
            try
            {
                totalGrossAmount = 0.00d;
                TotalTaxesOutputs = 0.00d;
                TotalTaxesWithHeld = 0.00d;
                GeneralDiscountBase = totalGrossAmount;
                
                int startIndex = 3;
                int LastIndex = this.Tables[t5].Rows.Last.Previous.Index;
                int nRows = LastIndex-startIndex;

                if (nRows > 1)
                {

                    for (int i = 1; i < nRows; i++)
                    {
                        this.Tables[t5].Rows[4].Delete();
                    }
                }


            }
            catch (Exception) { }
        }

        /// <summary>
        /// devuelve el valor de un enumerado de tipo xmlEnum
        /// </summary>
        /// <param name="e"> enumerado del cual se desea recuperar el valor</param>
        /// <returns>el valor correspondiente al enumerado, 
        /// <para>
        /// 
        /// <example>
        /// se tiene el siguiente enumerado:
        /// 
        /// <code>
        ///  [XmlTypeAttribute]
        /// public enum elementos
        /// {
        /// ["elemento 1"]
        /// item1,
        /// ["eliminado 2"]
        /// item2
        /// }
        /// </code>
        /// 
        /// la llamada:
        /// <code>
        /// ConvertToString(elementos.item1);
        /// </code>
        /// devulve: 
        /// 
        /// "elemento 1"
        /// </example>
        /// </para>
        /// 
        /// 
        /// </returns>
        private string ConvertToString(Enum e)
        {
            // Get the Type of the enum
            Type t = e.GetType();

            // Get the FieldInfo for the member field with the enums name
            FieldInfo info = t.GetField(e.ToString("G"));

            // Check to see if the XmlEnumAttribute is defined on this field
            if (!info.IsDefined(typeof(XmlEnumAttribute), false))
            {
                // If no XmlEnumAttribute then return the string version of the enum.
                return e.ToString("G");
            }

            // Get the XmlEnumAttribute
            object[] o = info.GetCustomAttributes(typeof(XmlEnumAttribute), false);
            XmlEnumAttribute att = (XmlEnumAttribute)o[0];
            return att.Name;
        }

        /// <summary>
        /// carga las entradas de el combobox indicado, con un array de strings
        /// </summary>
        /// <param name="cbx">combobox que se va a cargar</param>
        /// <param name="data">array de string con el que se va a cargar el combobox </param>
        private void LoadComboBox(ComboBoxContentControl cbx, string[] data)
        {
            try
            {
                int index = 0;
                for (int i = 0; i < data.Length; i++)
                {
                    cbx.DropDownListEntries.Add(data[i], data[i + 1], index);
                    i++; index++;
                }

            }
            catch (Exception)
            {
               
            }

        }
        
        /// <summary>
        /// método encargado de realizar las operaciones necesarias para agregar ó modificar detalles, 
        /// realiza los cálculos, inserta las nuevas lineas, uptualiza las demas tablas, descuentos y totales
        /// </summary>
        /// <param name="rowIndex">número de fila modicar o crear</param>
        /// <param name="newDetail"> si el valor es true, indica q se va a agregar una nueva fila, si es false indica que la fila se va a modificar</param>
        private void addDetail(int rowIndex, bool newDetail)
        {
            CultureInfo cInfo = new CultureInfo(this.Application.LanguageSettings.get_LanguageID(Microsoft.Office.Core.MsoAppLanguageID.msoLanguageIDUI));
            String language = cInfo.Name;

            string path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\Microsoft Office Word Facturae Add-In\Datos de Programa\Messages\" + language + ".xml";

            try
            {


                if (string.IsNullOrEmpty(this.Tables[t2].Rows[rowIndex].Cells[2].Range.Text.Trim(x).Trim()))
                    MessageBox.Show(LoadLabel(path,"ErrorMandatoryDescription"),LoadLabel(path,"captionDetails"), MessageBoxButtons.OK, MessageBoxIcon.Stop, MessageBoxDefaultButton.Button1);

                else
                {

                    string UD = this.Tables[t2].Rows[rowIndex].Cells[3].Range.Text.Trim(x).Trim();
                    string PRICE = this.Tables[t2].Rows[rowIndex].Cells[4].Range.Text.Trim(x).Trim();
                    string DISC = this.Tables[t2].Rows[rowIndex].Cells[5].Range.Text.Trim(x).Trim();
                    string IVA = this.Tables[t2].Rows[rowIndex].Cells[6].Range.Text.Trim(x).Trim();
                    string IRPF = this.Tables[t2].Rows[rowIndex].Cells[7].Range.Text.Trim(x).Trim();
                    double ud = 0;
                    double price = 0;
                    double discount = 0;
                    double iva = 0;
                    double irpf = 0;
                    double taxWithHeldAmount = 0;
                    double cost = 0;
                    double discountAmount = 0;
                    double taxableBase = 0;
                    double taxAmount = 0;

                    try
                    {
                        ud = double.Parse(UD, num);
                    }
                    catch (Exception)
                    {
                        txtUd.Range.Select();
                        throw new Exception(LoadLabel(path,"ErrorUnlegalLiteralsUd"));


                    }

                    try
                    {
                        price = double.Parse(PRICE, num);
                    }
                    catch (Exception)
                    {
                        txtPrice.Range.Select();
                        throw new Exception(LoadLabel(path,"ErrorUnlegalLiteralsPrice"));

                    }


                    cost = ud * price;

                    try
                    {
                        discount = double.Parse(DISC, num);

                    }
                    catch (Exception)
                    {
                        if (!string.IsNullOrEmpty(DISC))
                        {
                            txtDiscount.Range.Select();
                            throw new Exception(LoadLabel(path,"ErrorUnlegalLiteralsDesc"));


                        }

                    }

                    if (discount != 0)
                    {
                        discountAmount = cost * (discount / 100);
                    }

                    taxableBase = cost - discountAmount;

                    try
                    {
                        iva = double.Parse(IVA, num);
                    }
                    catch (Exception)
                    {
                        if (!string.IsNullOrEmpty(IVA))
                        {
                            cbxIVA.Range.Select();
                            throw new Exception(LoadLabel(path,"ErrorUnlegalLiteralsIVA"));

                        }
                    }

                    if (iva != 0)
                    {
                        taxAmount = taxableBase * (iva / 100);
                    }

                    try
                    {
                        irpf = double.Parse(IRPF, num);
                    }
                    catch (Exception)
                    {
                        if (!string.IsNullOrEmpty(IRPF))
                        {
                            txtIRPF.Range.Select();
                            throw new Exception(LoadLabel(path, "ErrorUnlegalLiteralsIRPF"));

                        }
                    }

                    if (irpf != 0)
                    {
                        taxWithHeldAmount = taxableBase * (irpf / 100);
                    }

                    double importe = taxableBase + taxAmount - taxWithHeldAmount;

                    int oldIndex = rowIndex; int newIndex = 0;

                    if (!newDetail)
                    {
                        newIndex = oldIndex;
                    }
                    else
                    {
                        object rowBefore = this.Tables[t2].Rows.Last;
                        this.Tables[t2].Rows.Add(ref rowBefore);
                        oldIndex = this.Tables[t2].Rows.Last.Index;
                        newIndex = this.Tables[t2].Rows.Last.Previous.Index;
                    }

                    //cargamos la fila con los datos generados    


                    this.Tables[t2].Rows[newIndex].Cells[1].Range.Text = this.Tables[t2].Rows[oldIndex].Cells[1].Range.Text.Trim(x).Trim();
                    this.Tables[t2].Rows[newIndex].Cells[2].Range.Text = this.Tables[t2].Rows[oldIndex].Cells[2].Range.Text.Trim(x).Trim();
                    this.Tables[t2].Rows[newIndex].Cells[3].Range.Text = string.Format(num, "{0:#,0.00}", ud);
                    this.Tables[t2].Rows[newIndex].Cells[4].Range.Text = string.Format(num, "{0:#,0.00}", price);
                    this.Tables[t2].Rows[newIndex].Cells[5].Range.Text = string.Format(num, "{0:#,0.00}", discount);
                    this.Tables[t2].Rows[newIndex].Cells[6].Range.Text = string.Format(num, "{0:#,0.00}", iva);
                    this.Tables[t2].Rows[newIndex].Cells[7].Range.Text = string.Format(num, "{0:#,0.00}", irpf);
                    this.Tables[t2].Rows[newIndex].Cells[8].Range.Text = string.Format(num, "{0:#,0.00}", taxableBase);
                    this.Tables[t2].Rows[newIndex].Cells[9].Range.Text = string.Format(num, "{0:#,0.00}", importe);

                    if (iva != 0)
                    {
                        setTaxType(iva, taxAmount, taxableBase);
                    }


                    totalGrossAmount += taxableBase;
                    TotalTaxesOutputs += taxAmount;
                    GeneralDiscountBase = totalGrossAmount;
                    TotalTaxesWithHeld += taxWithHeldAmount;


                    if (newDetail)
                    {
                        newIndex = oldIndex;

                        txtConcepto.Text = "";
                        txtUd.Text = "";
                        txtPrice.Text = "";
                        txtDiscount.Text = "";
                        cbxIVA.Text = "16";
                        txtTaxableBase.Text = "";
                        txtImporte.Text = "";
                    }

                    //ACTUALIZAR VALORES DE TABLA DE TOTALES 

                    updateResultsTable();

                }
            }
            catch (Exception exp)
            {

                MessageBox.Show(exp.Message,LoadLabel(path,"captionDetails"), MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);

            }
        }

   
        /// <summary>
        /// <para>se encarga de agregar o modifcar descuentos generales, estos se calculan sobre el importe bruto total.</para>
        /// <para>realiza los cálculos e inserta una nueva linea con los valores en la tabla de descuento</para>        /// 
        /// </summary>
        /// <param name="rowIndex">numero de fila a modificar o agregar </param>
        /// <param name="newDiscout">si el valor es true, indica q se va a agregar una nueva fila, si es false indica que la fila se va a modificar</param>
        private void addDiscount(int rowIndex, bool newDiscout)
        {
            try
            {

                if (string.IsNullOrEmpty(this.Tables[t3].Rows[rowIndex].Cells[1].Range.Text.Trim(x).Trim()))
                    MessageBox.Show("Debe especificar el concepto del detalle", "Descuentos", MessageBoxButtons.OK, MessageBoxIcon.Stop, MessageBoxDefaultButton.Button1);
                else
                {

                    string disc = this.Tables[t3].Rows[rowIndex].Cells[2].Range.Text.Trim(x).Trim();


                    double discount = double.Parse(disc, num);
                    GeneralDiscountBase = totalGrossAmount;
                    double importe = GeneralDiscountBase * discount / 100;

                    int oldIndex = rowIndex; int newIndex = 0;
                    if (!newDiscout)
                    {
                        newIndex = oldIndex;
                    }
                    else
                    {
                        object rowBefore = this.Tables[t3].Rows.Last;
                        this.Tables[t3].Rows.Add(ref rowBefore);
                        oldIndex = this.Tables[t3].Rows.Last.Index;
                        newIndex = this.Tables[t3].Rows.Last.Previous.Index;

                    }


                    //cargamos la fila con los datos generados 


                    this.Tables[t3].Rows[newIndex].Cells[1].Range.Text = this.Tables[t3].Rows[oldIndex].Cells[1].Range.Text.Trim(x).Trim();
                    this.Tables[t3].Rows[newIndex].Cells[2].Range.Text = string.Format(num, "{0:#,0.00}",discount);
                    this.Tables[t3].Rows[newIndex].Cells[3].Range.Text = string.Format(num,"{0:#,0.00}", importe);

                    totalGeneralDiscount += importe;
                    
                    if (newDiscout)
                    {
                        txtDiscountReason.Text = "";
                        txtDiscountRate.Text = "";
                    }

                  

                    updateResultsTable();
                }

            }
            
            catch (Exception)
            {
                MessageBox.Show("Alguno de los valores introducidos no es válido", "Descuentos", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
            }
        }

        /// <summary>
        /// elimina el descuento de la fila especificada
        /// </summary>
        /// <param name="rowIndex"> número de fila a eliminar</param>
        private void deleteDiscount(int rowIndex)
        {
            try
            {
               
                
                    string DiscountAmount = this.Tables[t3].Rows[rowIndex].Cells[3].Range.Text.Trim(x).Trim();

                    double importe = double.Parse(DiscountAmount, num);

                    totalGeneralDiscount -= importe;
                    //GeneralDiscountBase += importe;

                    updateResultsTable();
                
            }
            catch (Exception)
            {
                MessageBox.Show("Alguno de los valores introducidos no es válido", "Descuentos", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
            }
        }

        /// <summary>
        /// permite modicar los descuentos
        /// </summary>
        private void modifyDiscount()
        {
            try
            {
                enumerateTables();

                totalGeneralDiscount = 0.0d;

                if (this.Tables[t3].Rows.Count > 3)
                {
                    for (int i = 3; i < this.Tables[t3].Rows.Count; i++)
                    {
                        addDiscount(i, false);
                    }

                    cargarN_Fila(this.cbxnDiscount, t3);
                }
            }
            catch (Exception) { }
        }

        /// <summary>
        /// actualiza la tabla de totales en los apartados de Importe total bruto, descuentos generales, IRPF y Total a pagar, 
        /// ya que los correspondientes al IVA se actualizan con las operaciones de los detalles
        /// </summary>
        private void updateResultsTable()
        {
            try
            {
                this.Tables[t5].Rows[2].Cells[3].Range.Text = string.Format(num, "{0:#,0.00}", totalGrossAmount);
                this.Tables[t5].Rows[3].Cells[3].Range.Text = string.Format(num, "{0:#,0.00}", totalGeneralDiscount);
                this.Tables[t5].Rows.Last.Previous.Cells[3].Range.Text = string.Format(num, "{0:#,0.00}", TotalTaxesWithHeld);
                this.Tables[t5].Rows.Last.Cells[3].Range.Text = string.Format(num, "{0:#,0.00}", (((totalGrossAmount - totalGeneralDiscount) + TotalTaxesOutputs) - TotalTaxesWithHeld));
            }
            catch (Exception) { }
        }

        /// <summary>
        /// actualiza los valores de los combobox que contienen el número de línea, en las tablas de detalle y descuento, 
        /// recorre el numero de itemes de las tablas y agrega el numero de elemeto a los combobox, permitiendo saber cual fila se desea eliminar o modificar
        /// </summary>
        /// <param name="cbx">combobox a actualizar</param>
        /// <param name="tableIndex">indice de la tabla al que corresponde el combobox</param>
        private void cargarN_Fila(ComboBox cbx, int tableIndex)
        {
            
            try
            {
                if (this.Tables[tableIndex].Rows.Count > 3)
                {
                    DataTable table = new DataTable();
                    DataColumn cName = new DataColumn("Name");
                    DataColumn cValue = new DataColumn("Value");
                    table.Columns.Add(cName);
                    table.Columns.Add(cValue);

                    for (int i = 3; i < this.Tables[tableIndex].Rows.Count; i++)
                    {
                        table.Rows.Add((i - 2).ToString(), i.ToString());

                    }

                    cbx.DataSource = table;
                    cbx.DisplayMember = "Name";
                    cbx.ValueMember = "Value";
                }
            }
            catch (Exception) { }

        }
        
        /// <summary>
        /// establece las lineas correspondientes a IVA en la tabla de totales, ya que debe aparecer tantas lineas de Iva como diferentes tipos haya
        /// se especifica la base imponible y la cuota para cada tipo, los tipos iguales son acumulativos
        /// </summary>
        /// <param name="taxRate">porcentaje de IVA a aplicar</param>
        /// <param name="taxamount">importe del IVA</param>
        /// <param name="taxableBase">base imponible sobre la que aplica el IVA</param>
        private void setTaxType(double taxRate, double taxamount, double taxableBase)
        {
            CultureInfo cInfo = new CultureInfo(this.Application.LanguageSettings.get_LanguageID(Microsoft.Office.Core.MsoAppLanguageID.msoLanguageIDUI));
            String language = cInfo.Name;
            string path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\Microsoft Office Word Facturae Add-In\Datos de Programa\Messages\" + language + ".xml";
            try
            {
                string TB = string.Concat(LoadLabel(path,"InfoTaxablebaxe"), taxRate.ToString(), ")");
                string TA = string.Concat(LoadLabel(path, "Infotaxamount"), taxRate.ToString(), ")");


                int taxRows = this.Tables[t5].Rows.Last.Previous.Index - 3;
                bool asigned = false;

                if (taxRows >= 1)
                {
                    for (int i = 1; i < taxRows; i++)
                    {
                        string amount = this.Tables[t5].Rows[i + 3].Cells[2].Range.Text.Trim(x).Trim();
                        if (amount.ToLower().Equals(TB.ToLower()))
                        {
                            double tb = double.Parse(this.Tables[t5].Rows[i + 3].Cells[3].Range.Text.Trim(x).Trim(), num);
                            double ta = double.Parse(this.Tables[t5].Rows[i + 4].Cells[3].Range.Text.Trim(x).Trim(), num);

                            tb += taxableBase;
                            ta += taxamount;


                            if ( ta != 0)
                            {                           
                            this.Tables[t5].Rows[i + 3].Cells[3].Range.Text = string.Format(num, "{0:#,0.00}", tb);
                            this.Tables[t5].Rows[i + 4].Cells[3].Range.Text = string.Format(num, "{0:#,0.00}", ta);                                                           
                            }
                            else
                            {
                                this.Tables[t5].Rows[i + 3].Delete();
                                this.Tables[t5].Rows[i + 3].Delete();
                            }

                            i++;
                            asigned = true;
                            break;
                        }

                    }
                    if (!asigned)
                    {
                        newTaxType(TB, TA, taxamount, taxableBase);
                    }
                }
            }
            catch (Exception) { }

        }
        
        /// <summary>
        /// se utiliza para insertar los nuevos tipos de IVA
        /// </summary>
        /// <param name="taxType">linea que se utilzara para referirse al tipo del IVA. ejemplo Base Imponible(IVA 16)</param>
        /// <param name="amountPrefix">linea que se utilzara para referirse a la cuota del IVA. ejemplo Cuota(IVA 16)</param>
        /// <param name="taxAmount">importe del IVA</param>
        /// <param name="taxableBase">base sobre la que se aplica el IVA</param>
        private void newTaxType(string taxType, string amountPrefix, double taxAmount, double taxableBase)
        {
            try
            {
                
                    object rowBefore = this.Tables[t5].Rows.Last.Previous;
                    this.Tables[t5].Rows.Add(ref rowBefore);
                    int index = this.Tables[t5].Rows.Last.Previous.Previous.Index;
                    this.Tables[t5].Rows[index].Cells[2].Range.Text = taxType;
                    this.Tables[t5].Rows[index].Cells[3].Range.Text = string.Format(num, "{0:#,0.00}", taxableBase);
                    rowBefore = this.Tables[t5].Rows.Last.Previous;
                    this.Tables[t5].Rows.Add(ref rowBefore);
                    index = this.Tables[t5].Rows.Last.Previous.Previous.Index;
                    this.Tables[t5].Rows[index].Cells[2].Range.Text = amountPrefix;
                    this.Tables[t5].Rows[index].Cells[3].Range.Text = string.Format(num, "{0:#,0.00}", taxAmount);
               
            }
            catch (Exception) { }
        }

        /// <summary>
        /// método que permite bloquear el documento para que no pueda ser editado cuando sea una factura recibida o se haya emitido
        /// agrupa las tablas, y bloquea los contentControls
        /// </summary>
        private void protectIssuedDocument()
        {
            try
            {
                string status = txtStatus.Text.Trim();
                int tableIndex = 1;
                if (!string.IsNullOrEmpty(status))
                {
                    if (status.ToUpper().Equals("ISSUED") || status.ToUpper().Equals("RECEIVED"))
                    {

                        try
                        {

                            foreach (Microsoft.Office.Interop.Word.ContentControl control in this.Application.ActiveDocument.ContentControls)
                            {                                
                                    control.LockContentControl = true;
                                    control.LockContents = true;
                               
                            }
                        }
                        catch (Exception) { }

                        try
                        {

                            foreach (Word.Table table in this.Application.ActiveDocument.Tables)
                            {
                                Word.Range range = table.Range;
                                range.Select();
                                this.Controls.AddGroupContentControl("groupControl" + tableIndex.ToString());
                                tableIndex++;
                            }
                        }
                        catch (Exception) { }

                        try
                        {
                            this.btAddDetails.Dispose();
                            this.btAddDiscount.Dispose();
                            this.btDeleteDetail.Dispose();
                            this.btDeleteDiscount.Dispose();
                            this.btModifyDetail.Dispose();
                            this.btModifyDiscount.Dispose();
                            this.cbxnDetails.Dispose();
                            this.cbxnDiscount.Dispose();

                            this.lbnDetails.Text = "";
                            this.lbnDiscounts.Text = "";

                            
                        }
                        catch (Exception) { }


                    }
                    this.dtpIssueDate.Range.Select();
                }

            }
            catch (Exception) { }

        }
                
        #endregion        

        private void txtUd_Exiting(object sender, ContentControlExitingEventArgs e)
            {
            try
            {
                double mVar = double.Parse(txtUd.Text,num);
                txtUd.Text = string.Format(num, "{0:#,0.00}", mVar);            

            }
            catch (Exception) { }
        }

        /// <summary>
        /// verifica el valor introducido para el descuento de linea, e indica al usuario si el valor es negativo
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void txtDiscount_Exiting(object sender, ContentControlExitingEventArgs e)
        {
            try
            {
                if (!string.IsNullOrEmpty(txtDiscount.Text))
                {
                    double discount = double.Parse(txtDiscount.Text.Trim(),num);
                    if (discount < 0)
                    {
                        throw new Exception("negativeDiscountRate");
                    }
                    else
                    {
                        txtDiscount.Text = string.Format(num, "{0:#,0.00}", discount);
                    }
                }

            }
            catch (Exception ex)
            {
                if (ex.Message.Equals("negativeDiscountRate"))
                {
                    MessageBox.Show(LoadLabel(messagePath,"ErrorNegativeDiscount"),LoadLabel(messagePath,"captionDetails"), MessageBoxButtons.OK, MessageBoxIcon.Stop, MessageBoxDefaultButton.Button1);
                    txtDiscount.Range.Select();
                }

            }
        }


        /// <summary>
        /// verifica el valor introducido para el descuento general, e indica al usuario si el valor es negativo
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void txtDiscountRate_Exiting(object sender, ContentControlExitingEventArgs e)
        {
            try
            {
                if (!string.IsNullOrEmpty(txtDiscountRate.Text))
                {
                    double discount = double.Parse(txtDiscountRate.Text.Trim(),num);
                    if (discount < 0)
                    {
                        throw new Exception("negativeDiscountRate");
                    }
                    else
                    {
                        txtDiscountRate.Text = string.Format(num, "{0:#,0.00}", discount);
                    }
                }

            }
            catch (Exception ex)
            {
                if (ex.Message.Equals("negativeDiscountRate"))
                {
                    MessageBox.Show("El porcentaje a descontar debe ser positivo", "Descuentos", MessageBoxButtons.OK, MessageBoxIcon.Stop, MessageBoxDefaultButton.Button1);
                    txtDiscountRate.Range.Select();
                }

            }
        }


        /// <summary>
        /// enumerado de codigos de país, incluidos en el esquema de facturae, se utilizan para cargar los combos de paises
        /// </summary>
        private enum CurrencyCodeType
        {

            /// <comentarios/>
            AFN,

            /// <comentarios/>
            ALL,

            /// <comentarios/>
            AMD,

            /// <comentarios/>
            ANG,

            /// <comentarios/>
            AOA,

            /// <comentarios/>
            ARS,

            /// <comentarios/>
            AUD,

            /// <comentarios/>
            AWG,

            /// <comentarios/>
            AZN,

            /// <comentarios/>
            BAD,

            /// <comentarios/>
            BBD,

            /// <comentarios/>
            BDT,

            /// <comentarios/>
            BGN,

            /// <comentarios/>
            BHD,

            /// <comentarios/>
            BIF,

            /// <comentarios/>
            BMD,

            /// <comentarios/>
            BND,

            /// <comentarios/>
            BOB,

            /// <comentarios/>
            BRL,

            /// <comentarios/>
            BRR,

            /// <comentarios/>
            BSD,

            /// <comentarios/>
            BWP,

            /// <comentarios/>
            BYR,

            /// <comentarios/>
            BZD,

            /// <comentarios/>
            CAD,

            /// <comentarios/>
            CDF,

            /// <comentarios/>
            CDP,

            /// <comentarios/>
            CHF,

            /// <comentarios/>
            CLP,

            /// <comentarios/>
            CNY,

            /// <comentarios/>
            COP,

            /// <comentarios/>
            CRC,

            /// <comentarios/>
            CUP,

            /// <comentarios/>
            CVE,

            /// <comentarios/>
            CZK,

            /// <comentarios/>
            DJF,

            /// <comentarios/>
            DKK,

            /// <comentarios/>
            DOP,

            /// <comentarios/>
            DRP,

            /// <comentarios/>
            DZD,

            /// <comentarios/>
            EEK,

            /// <comentarios/>
            EGP,

            /// <comentarios/>
            ESP,

            /// <comentarios/>
            ETB,

            /// <comentarios/>
            EUR,

            /// <comentarios/>
            FJD,

            /// <comentarios/>
            FKP,

            /// <comentarios/>
            GBP,

            /// <comentarios/>
            GEK,

            /// <comentarios/>
            GHC,

            /// <comentarios/>
            GIP,

            /// <comentarios/>
            GMD,

            /// <comentarios/>
            GNF,

            /// <comentarios/>
            GTQ,

            /// <comentarios/>
            GWP,

            /// <comentarios/>
            GYD,

            /// <comentarios/>
            HKD,

            /// <comentarios/>
            HNL,

            /// <comentarios/>
            HRK,

            /// <comentarios/>
            HTG,

            /// <comentarios/>
            HUF,

            /// <comentarios/>
            IDR,

            /// <comentarios/>
            ILS,

            /// <comentarios/>
            INR,

            /// <comentarios/>
            IQD,

            /// <comentarios/>
            IRR,

            /// <comentarios/>
            ISK,

            /// <comentarios/>
            JMD,

            /// <comentarios/>
            JOD,

            /// <comentarios/>
            JPY,

            /// <comentarios/>
            KES,

            /// <comentarios/>
            KGS,

            /// <comentarios/>
            KHR,

            /// <comentarios/>
            KMF,

            /// <comentarios/>
            KPW,

            /// <comentarios/>
            KRW,

            /// <comentarios/>
            KWD,

            /// <comentarios/>
            KYD,

            /// <comentarios/>
            KZT,

            /// <comentarios/>
            LAK,

            /// <comentarios/>
            LBP,

            /// <comentarios/>
            LKR,

            /// <comentarios/>
            LRD,

            /// <comentarios/>
            LSL,

            /// <comentarios/>
            LTL,

            /// <comentarios/>
            LVL,

            /// <comentarios/>
            LYD,

            /// <comentarios/>
            MAD,

            /// <comentarios/>
            MDL,

            /// <comentarios/>
            MGF,

            /// <comentarios/>
            MNC,

            /// <comentarios/>
            MNT,

            /// <comentarios/>
            MOP,

            /// <comentarios/>
            MRO,

            /// <comentarios/>
            MUR,

            /// <comentarios/>
            MVR,

            /// <comentarios/>
            MWK,

            /// <comentarios/>
            MXN,

            /// <comentarios/>
            MYR,

            /// <comentarios/>
            MZM,

            /// <comentarios/>
            NGN,

            /// <comentarios/>
            NIC,

            /// <comentarios/>
            NIO,

            /// <comentarios/>
            NIS,

            /// <comentarios/>
            NOK,

            /// <comentarios/>
            NPR,

            /// <comentarios/>
            NZD,

            /// <comentarios/>
            OMR,

            /// <comentarios/>
            PAB,

            /// <comentarios/>
            PEI,

            /// <comentarios/>
            PEN,

            /// <comentarios/>
            PES,

            /// <comentarios/>
            PGK,

            /// <comentarios/>
            PHP,

            /// <comentarios/>
            PKR,

            /// <comentarios/>
            PLN,

            /// <comentarios/>
            PYG,

            /// <comentarios/>
            QAR,

            /// <comentarios/>
            RMB,

            /// <comentarios/>
            RON,

            /// <comentarios/>
            RUB,

            /// <comentarios/>
            RWF,

            /// <comentarios/>
            SAR,

            /// <comentarios/>
            SBD,

            /// <comentarios/>
            SCR,

            /// <comentarios/>
            SDP,

            /// <comentarios/>
            SEK,

            /// <comentarios/>
            SGD,

            /// <comentarios/>
            SHP,

            /// <comentarios/>
            SKK,

            /// <comentarios/>
            SLL,

            /// <comentarios/>
            SOL,

            /// <comentarios/>
            SOS,

            /// <comentarios/>
            SRD,

            /// <comentarios/>
            STD,

            /// <comentarios/>
            SVC,

            /// <comentarios/>
            SYP,

            /// <comentarios/>
            SZL,

            /// <comentarios/>
            THB,

            /// <comentarios/>
            TJS,

            /// <comentarios/>
            TMM,

            /// <comentarios/>
            TND,

            /// <comentarios/>
            TOP,

            /// <comentarios/>
            TPE,

            /// <comentarios/>
            TRY,

            /// <comentarios/>
            TTD,

            /// <comentarios/>
            TWD,

            /// <comentarios/>
            TZS,

            /// <comentarios/>
            UAH,

            /// <comentarios/>
            UGS,

            /// <comentarios/>
            USD,

            /// <comentarios/>
            UYP,

            /// <comentarios/>
            UYU,

            /// <comentarios/>
            VEF,

            /// <comentarios/>
            VND,

            /// <comentarios/>
            VUV,

            /// <comentarios/>
            WST,

            /// <comentarios/>
            XAF,

            /// <comentarios/>
            XCD,

            /// <comentarios/>
            XOF,

            /// <comentarios/>
            YER,

            /// <comentarios/>
            ZAR,

            /// <comentarios/>
            ZMK,

            /// <comentarios/>
            ZWD,
        }


        private string LoadLabel(string path, string tag)
        {
            string label = " ";
            try
            {
                XmlDocument xmldoc = new XmlDocument();
                xmldoc.Load(path);
                string lb = xmldoc.GetElementsByTagName(tag).Item(0).InnerText;
                if (!string.IsNullOrEmpty(lb))
                    label = lb;

                return label;

            }
            catch (Exception)
            {
                return label;
            }
        }

        private void txtPrice_Exiting(object sender, ContentControlExitingEventArgs e)
        {
            try
            {
                double xVar = double.Parse(txtPrice.Text,num);
                txtPrice.Text = string.Format(num, "{0:#,0.00}", xVar);
            }
            catch (Exception) { }
         
        }

        private void cbxIVA_Exiting(object sender, ContentControlExitingEventArgs e)
        {
            try
            {
                double xVar = double.Parse(cbxIVA.Text,num);
                cbxIVA.Text = string.Format(num, "{0:#,0.00}", xVar);



            }
            catch (Exception) { }
        }

        private void txtIRPF_Exiting(object sender, ContentControlExitingEventArgs e)
        {
            try
            {
                double xVar = double.Parse(txtIRPF.Text,num);
                txtIRPF.Text = string.Format(num, "{0:#,0.00}", xVar);
            }
            catch (Exception) { }
        }

       

        /// <summary>
        ///Busca el ContentControl con el nombre especificado y devuelve el texto digitado
        /// </summary>
        /// <param name="tag">enumerado de tipo ControlList.tag que representa el nombre del contentControl</param>
        /// <returns>el Valor del contentControl con nombre = tag</returns>
        public string getControlValueByTag(string tag)
        {
            string value = null;
            if (string.IsNullOrEmpty(tag))
                return value;
            foreach (Microsoft.Office.Interop.Word.ContentControl item in this.ContentControls)
            {
                if (!string.IsNullOrEmpty(item.Tag))
                {
                    if (item.Tag.Equals(tag))
                    {
                        if (string.IsNullOrEmpty(item.Range.Text))
                            return value;
                        value = item.Range.Text.Trim();
                        break;
                    }
                }
            }

            return value;


        }

        /// <summary>
        /// Busca el texto seleccionado en un DropDownListContentControl y devuelve el valor correspondiente
        /// </summary>
        /// <param name="tag">Representa el nombre del DropDownListContentControl del que se desea obtener el valor</param>
        /// <param name="selectedItem">Texto seleccionado en el DropDownListContentControl</param>
        /// <returns>el valor correspondiente al texto seleccionado en el DropDownListContentControl</returns>
        private string controlValue(string tag, string selectedItem)
        {
            string value = "";

            if (string.IsNullOrEmpty(tag))
                return value;

            /*buscamos el combobox indicado*/
            foreach (Microsoft.Office.Interop.Word.ContentControl item in this.ContentControls)
            {
                if (!string.IsNullOrEmpty(item.Tag))
                {
                    if (item.Tag.Equals(tag))
                    {
                        /*si lo encontramos buscamos el valor correspondiente al texto seleccionado*/
                        foreach (ContentControlListEntry entry in item.DropdownListEntries)
                        {
                            if (!string.IsNullOrEmpty(item.Tag))
                            {
                                if (entry.Text.ToLower().Equals(selectedItem.ToLower()))
                                {
                                    value = entry.Value; break;
                                }
                            }

                        } break;
                    }
                }
            }
            return value;
        }

        private void cbxCountryBP_Exiting(object sender, ContentControlExitingEventArgs e)
        {
            validarBPCif(false);
        }

        private void cbxCountryTH_Exiting(object sender, ContentControlExitingEventArgs e)
        {
            validarTHCif(false);
        }

        private void cbxCountryEM_Exiting(object sender, ContentControlExitingEventArgs e)
        {
            validarSPCif(false);
        }

        private void txtCifEM_Exiting(object sender, ContentControlExitingEventArgs e)
        {
            validarSPCif(true);
        }



        private void txtCifBP_Exiting(object sender, ContentControlExitingEventArgs e)
        {
            validarBPCif(true);
        }

        private void txtCIFTH_Entering(object sender, ContentControlEnteringEventArgs e)
        {
            validarTHCif(true);
        }


        private void validarSPCif(bool cifvalidation)
        {
            string country3 = controlValue("SP_CountryCode", cbxCountryEM.Range.Text.Trim());
            
            if (string.IsNullOrEmpty(country3)&& !cifvalidation)
            {
                MessageBox.Show(LoadLabel(messagePath, "countrynotinlist"), "Facturae", MessageBoxButtons.OK, MessageBoxIcon.Stop, MessageBoxDefaultButton.Button1);
                cbxCountryEM.Range.Select();
            }
            else
            {
                if (Validations.validarCif(txtCifEM.Range.Text.Trim(), country3))
                {
                    if (txtCifEM.Range.Text.Trim().Length == 9)
                    {
                        string country2 = Validations.ConvertToString(Validations.convertToCountryType(country3));
                        txtCifEM.Range.Text = string.Concat(country2, txtCifEM.Range.Text.Trim());
                    }
                }
                else
                {
                    MessageBox.Show(LoadLabel(messagePath, "ErrorInvalidCIFSP"), "Facturae", MessageBoxButtons.OK, MessageBoxIcon.Stop, MessageBoxDefaultButton.Button1);
                }
            }
        }

        private void validarBPCif(bool cifvalidation)
        {
            string country3 = controlValue("BP_CountryCode", cbxCountryBP.Range.Text.Trim());

            if (string.IsNullOrEmpty(country3)&& !cifvalidation)
            {
                MessageBox.Show(LoadLabel(messagePath, "countrynotinlist"), "Facturae", MessageBoxButtons.OK, MessageBoxIcon.Stop, MessageBoxDefaultButton.Button1);
                cbxCountryBP.Range.Select();
            }
            else
            {
                if (Validations.validarCif(txtCifBP.Range.Text.Trim(), country3))
                {
                    if (txtCifBP.Range.Text.Trim().Length == 9)
                    {
                        string country2 = Validations.ConvertToString(Validations.convertToCountryType(country3));
                        txtCifBP.Range.Text = string.Concat(country2, txtCifBP.Range.Text.Trim());
                    }
                }
                else
                {
                    MessageBox.Show(LoadLabel(messagePath, "ErrorInvalidCIFBP"), "Facturae", MessageBoxButtons.OK, MessageBoxIcon.Stop, MessageBoxDefaultButton.Button1);
                }
            }
        }

        private void validarTHCif(bool cifvalidation)
        {
            string country3 = controlValue("TH_CountryCode", cbxCountryTH.Range.Text.Trim());

            if (string.IsNullOrEmpty(country3)&& !cifvalidation)
            {
                MessageBox.Show(LoadLabel(messagePath, "countrynotinlist"), "Facturae", MessageBoxButtons.OK, MessageBoxIcon.Stop, MessageBoxDefaultButton.Button1);
                cbxCountryTH.Range.Select();
            }
            else
            {
                if (Validations.validarCif(txtCIFTH.Range.Text.Trim(), country3))
                {
                    if (txtCIFTH.Range.Text.Trim().Length == 9)
                    {
                        string country2 = Validations.ConvertToString(Validations.convertToCountryType(country3));
                        txtCIFTH.Range.Text = string.Concat(country2, txtCIFTH.Range.Text.Trim());
                    }
                }
                else
                {
                    MessageBox.Show(LoadLabel(messagePath, "ErrorInvalidCIFTH"), "Facturae", MessageBoxButtons.OK, MessageBoxIcon.Stop, MessageBoxDefaultButton.Button1);
                }
            }
        }
       
    }

}



        
    

 